home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Appls / test / faced.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-30  |  6.9 KB  |  441 lines  |  [TEXT/????]

  1. /* Simple bitmap editor.
  2.    Uses ".face" file format (48x48).
  3.    
  4.    TO DO:
  5.        - fix row/col confusion
  6.     - connect dots given by mouse move?
  7.     - optimize drawing of consequtive black squares
  8.     - add open... command
  9.     - add flexible input format
  10.     - support X bitmap format
  11.     */
  12.  
  13. #include <stdio.h>
  14. #include "stdwin.h"
  15.  
  16. #define ROWS 48
  17. #define COLS 48
  18. #define SIZE (ROWS < COLS ? ROWS : COLS)
  19.  
  20. #define BITS 16 /* Bits per word */
  21.  
  22. char bit[ROWS][COLS];
  23.  
  24. int xscale= 5;
  25. int yscale= 5;
  26.  
  27. WINDOW *win;
  28.  
  29. int changed= 0;
  30.  
  31.  
  32. main(argc, argv)
  33.     int argc;
  34.     char **argv;
  35. {
  36.     FILE *fp;
  37.     
  38.     winitargs(&argc, &argv);
  39.     
  40.     if (argc > 1) {
  41.         fp= fopen(argv[1], "r");
  42.         if (fp == NULL) {
  43.             wdone();
  44.             perror(argv[1]);
  45.             exit(1);
  46.         }
  47.         input(fp);
  48.         fclose(fp);
  49.     }
  50.     
  51.     setup();
  52.     
  53.  
  54.     for (;;) {
  55.         editing();
  56.         
  57.         if (changed) {
  58.             switch (waskync("Save changes?", 1)) {
  59.             case 1:
  60.                 if (!save(argc > 1 ? argv[1] : NULL))
  61.                     continue;
  62.                 break;
  63.             case -1:
  64.                 continue;
  65.             }
  66.         }
  67.         break; /* Out of loop */
  68.     }
  69.     
  70.     wdone();
  71.     exit(0);
  72. }
  73.  
  74. save(name)
  75.     char *name;
  76. {
  77.     FILE *fp;
  78.     char namebuf[256];
  79.     
  80.     namebuf[0]= '\0';
  81.     if (name == NULL) {
  82.         if (!waskfile("Save as", namebuf, sizeof namebuf, 1))
  83.             return 0;
  84.         name= namebuf;
  85.     }
  86.     fp= fopen(name, "w");
  87.     if (fp == NULL) {
  88.         wperror(name);
  89.         return 0;
  90.     }
  91.     output(fp);
  92.     fclose(fp);
  93.     return 1;
  94. }
  95.  
  96. #define MAIN_MENU    1
  97.  
  98. #define QUIT_ITEM    0
  99.  
  100. #define OP_MENU        2
  101.  
  102. #define CLEAR_ITEM    0
  103. #define SET_ITEM    1
  104. #define INVERT_ITEM    2
  105. #define TRANS_MAJ_ITEM    3
  106. #define TRANS_MIN_ITEM    4
  107. #define ROT_LEFT_ITEM    5
  108. #define ROT_RIGHT_ITEM    6
  109. #define FLIP_HOR_ITEM    7
  110. #define FLIP_VERT_ITEM    8
  111.  
  112. #define NOPS        9
  113.  
  114. extern int (*oplist[])(); /* Forward */
  115. drawproc(); /* Forward */
  116.  
  117. int text_only;
  118.  
  119. setup()
  120. {
  121.     MENU *mp;
  122.     int width, height;
  123.     
  124.     if (wlineheight() == 1)
  125.         text_only= xscale= yscale= 1;
  126.     
  127.     wsetdefwinsize(COLS*xscale, ROWS*yscale);
  128.     
  129.     mp= wmenucreate(MAIN_MENU, "Faced");
  130.     wmenuadditem(mp, "Quit", 'Q');
  131.     mp= wmenucreate(OP_MENU, "Operations");
  132.     wmenuadditem(mp, "Clear all", -1);
  133.     wmenuadditem(mp, "Set all", -1);
  134.     wmenuadditem(mp, "Invert", -1);
  135.     wmenuadditem(mp, "Transpose major", -1);
  136.     wmenuadditem(mp, "Transpose minor", -1);
  137.     wmenuadditem(mp, "Rotate left", -1);
  138.     wmenuadditem(mp, "Rotate right", -1);
  139.     wmenuadditem(mp, "Flip horizontal", -1);
  140.     wmenuadditem(mp, "Flip vertical", -1);
  141.     
  142.     win= wopen("faced", drawproc);
  143.     if (win == NULL) {
  144.         wmessage("Can't open window");
  145.         return;
  146.     }
  147.     wsetdocsize(win, COLS*xscale, ROWS*yscale);
  148. }
  149.  
  150. editing()
  151. {
  152.     int value= 0;
  153.     
  154.     for (;;) {
  155.         EVENT e;
  156.         
  157.         wgetevent(&e);
  158.         switch (e.type) {
  159.         case WE_MOUSE_DOWN:
  160.             value= !getbit(e.u.where.h/xscale, e.u.where.v/yscale);
  161.         case WE_MOUSE_MOVE:
  162.         case WE_MOUSE_UP:
  163.             setbit(e.u.where.h/xscale, e.u.where.v/yscale, value);
  164.             break;
  165.         case WE_COMMAND:
  166.             switch (e.u.command) {
  167.             case WC_CLOSE:
  168.                 return;
  169.             case WC_CANCEL:
  170.                 changed= 0;
  171.                 return;
  172.             }
  173.         case WE_CLOSE:
  174.             return;
  175.         case WE_MENU:
  176.             switch (e.u.m.id) {
  177.             case MAIN_MENU:
  178.                 switch (e.u.m.item) {
  179.                 case QUIT_ITEM:
  180.                     return;
  181.                 }
  182.                 break;
  183.             case OP_MENU:
  184.                 if (e.u.m.item >= 0 && e.u.m.item < NOPS) {
  185.                     (*oplist[e.u.m.item])();
  186.                     wchange(win, 0, 0,
  187.                         COLS*xscale, ROWS*yscale);
  188.                     changed= 1;
  189.                 }
  190.                 break;
  191.             }
  192.         }
  193.     }
  194. }
  195.  
  196. int
  197. getbit(col, row)
  198. {
  199.     if (row >= 0 && row < ROWS && col >= 0 && col < COLS)
  200.         return bit[row][col];
  201.     else
  202.         return 0;
  203. }
  204.  
  205. setbit(col, row, value)
  206. {
  207.     if (row >= 0 && row < ROWS && col >= 0 && col < COLS &&
  208.             bit[row][col] != value) {
  209.         changed= 1;
  210.         bit[row][col]= value;
  211.         wchange(win, col*xscale, row*yscale,
  212.             (col+1)*xscale, (row+1)*yscale);
  213.     }
  214. }
  215.  
  216. drawproc(win, left, top, right, bottom)
  217.     WINDOW *win;
  218. {
  219.     int row, col;
  220.     
  221.     if (left < 0)
  222.         left= 0;
  223.     if (right > COLS*xscale)
  224.         right= COLS*xscale;
  225.     if (top < 0)
  226.         top= 0;
  227.     if (bottom > ROWS*yscale)
  228.         bottom= ROWS*yscale;
  229.     
  230.     for (row= top/yscale; row*yscale < bottom; ++row) {
  231.         for (col= left/xscale; col*xscale < right; ++col) {
  232.             if (bit[row][col]) {
  233.                 if (text_only)
  234.                     wdrawchar(col, row, 'x');
  235.                 else
  236.                     wpaint(col*xscale, row*yscale,
  237.                         (col+1)*xscale, (row+1)*yscale);
  238.             }
  239.         }
  240.     }
  241. }
  242.  
  243.  
  244. /* File I/O routines */
  245.  
  246. input(fp)
  247.     FILE *fp;
  248. {
  249.     int row;
  250.     
  251.     for (row= 0; row < ROWS; ++row) {
  252.         read_row(fp, row);
  253.     }
  254. }
  255.  
  256. read_row(fp, row)
  257.     FILE *fp;
  258.     int row;
  259. {
  260.     int left= 0;
  261.     long ibuf;
  262.     int col;
  263.     
  264.     for (col= 0; col < COLS; ++col) {
  265.         if (left <= 0) {
  266.             if (fscanf(fp, " 0x%4lx,", &ibuf) != 1) {
  267.                 wdone();
  268.                 fprintf(stderr,
  269.                     "Bad input format, row %d\n", row);
  270.                 exit(1);
  271.             }
  272.             left= BITS;
  273.         }
  274.         --left;
  275.         bit[row][col]= (ibuf >> left) & 1;
  276.     }
  277. }
  278.  
  279. output(fp)
  280.     FILE *fp;
  281. {
  282.     int row;
  283.     
  284.     for (row= 0; row < ROWS; ++row)
  285.         write_row(fp, row);
  286. }
  287.  
  288. write_row(fp, row)
  289.     FILE *fp;
  290.     int row;
  291. {
  292.     int col;
  293.     int left= BITS;
  294.     long ibuf= 0;
  295.     
  296.     for (col= 0; col < COLS; ++col) {
  297.         if (left <= 0) {
  298.             fprintf(fp, "0x%04lX,", ibuf);
  299.             ibuf= 0;
  300.             left= BITS;
  301.         }
  302.         --left;
  303.         if (bit[row][col]) {
  304.             ibuf |= 1<<left;
  305.         }
  306.     }
  307.     if (left < BITS)
  308.         fprintf(fp, "0x%04lX,", ibuf);
  309.     fprintf(fp, "\n");
  310. }
  311.  
  312.  
  313. /* Data manipulation routines */
  314.  
  315. clear_bits()
  316. {
  317.     int row, col;
  318.     
  319.     for (row= 0; row < ROWS; ++row)
  320.         for (col= 0; col < COLS; ++col)
  321.             bit[row][col]= 0;
  322. }
  323.  
  324. set_bits()
  325. {
  326.     int row, col;
  327.     
  328.     for (row= 0; row < ROWS; ++row)
  329.         for (col= 0; col < COLS; ++col)
  330.             bit[row][col]= 1;
  331. }
  332.  
  333. invert_bits()
  334. {
  335.     int row, col;
  336.     
  337.     for (row= 0; row < ROWS; ++row)
  338.         for (col= 0; col < COLS; ++col)
  339.             bit[row][col]= !bit[row][col];
  340. }
  341.  
  342. transpose_major()
  343. {
  344.     int row, col;
  345.     char tmp;
  346.     
  347.     for (row= 0; row < SIZE; ++row) {
  348.         for (col= 0; col < row; ++col) {
  349.             tmp= bit[row][col];
  350.             bit[row][col]= bit[col][row];
  351.             bit[col][row]= tmp;
  352.         }
  353.     }
  354. }
  355.  
  356. transpose_minor()
  357. {
  358.     int row, col;
  359.     char tmp;
  360.     
  361.     for (row= 0; row < SIZE; ++row) {
  362.         for (col= 0; col < SIZE-1-row; ++col) {
  363.             tmp= bit[row][col];
  364.             bit[row][col]= bit[SIZE-1-col][SIZE-1-row];
  365.             bit[SIZE-1-col][SIZE-1-row]= tmp;
  366.         }
  367.     }
  368. }
  369.  
  370. rotate_left()
  371. {
  372.     int row, col;
  373.     char tmp;
  374.     
  375.     for (row= 0; row < SIZE/2; ++row) {
  376.         for (col= 0; col < SIZE/2; ++col) {
  377.             tmp= bit[row][col];
  378.             bit[row][col]= bit[col][SIZE-1-row];
  379.             bit[col][SIZE-1-row]= bit[SIZE-1-row][SIZE-1-col];
  380.             bit[SIZE-1-row][SIZE-1-col]= bit[SIZE-1-col][row];
  381.             bit[SIZE-1-col][row]= tmp;
  382.         }
  383.     }
  384. }
  385.  
  386. rotate_right()
  387. {
  388.     int row, col;
  389.     char tmp;
  390.     
  391.     for (row= 0; row < SIZE/2; ++row) {
  392.         for (col= 0; col < SIZE/2; ++col) {
  393.             tmp= bit[row][col];
  394.             bit[row][col]= bit[SIZE-1-col][row];
  395.             bit[SIZE-1-col][row]= bit[SIZE-1-row][SIZE-1-col];
  396.             bit[SIZE-1-row][SIZE-1-col]= bit[col][SIZE-1-row];
  397.             bit[col][SIZE-1-row]= tmp;
  398.         }
  399.     }
  400. }
  401.  
  402. flip_horizontal()
  403. {
  404.     int row, col;
  405.     char tmp;
  406.     
  407.     for (row= 0; row < ROWS; ++row) {
  408.         for (col= 0; col < COLS/2; ++col) {
  409.             tmp= bit[row][col];
  410.             bit[row][col]= bit[row][COLS-1-col];
  411.             bit[row][COLS-1-col]= tmp;
  412.         }
  413.     }
  414. }
  415.  
  416. flip_vertical()
  417. {
  418.     int row, col;
  419.     char tmp;
  420.     
  421.     for (row= 0; row < ROWS/2; ++row) {
  422.         for (col= 0; col < COLS; ++col) {
  423.             tmp= bit[row][col];
  424.             bit[row][col]= bit[ROWS-1-row][col];
  425.             bit[ROWS-1-row][col]= tmp;
  426.         }
  427.     }
  428. }
  429.  
  430. int (*oplist[])() = {
  431.     clear_bits,
  432.     set_bits,
  433.     invert_bits,
  434.     transpose_major,
  435.     transpose_minor,
  436.     rotate_left,
  437.     rotate_right,
  438.     flip_horizontal,
  439.     flip_vertical,
  440. };
  441.